home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / zope / interface / declarations.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  34.7 KB  |  1,265 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''Implementation of interface declarations
  5.  
  6. There are three flavors of declarations:
  7.  
  8.   - Declarations are used to simply name declared interfaces.
  9.  
  10.   - ImplementsDeclarations are used to express the interfaces that a
  11.     class implements (that instances of the class provides).
  12.  
  13.     Implements specifications support inheriting interfaces.
  14.  
  15.   - ProvidesDeclarations are used to express interfaces directly
  16.     provided by objects.
  17.     
  18.  
  19. $Id: declarations.py 27081 2004-08-12 19:56:31Z srichter $
  20. '''
  21. import sys
  22. import weakref
  23. from zope.interface.interface import InterfaceClass, Specification
  24. from ro import mergeOrderings, ro
  25. import exceptions
  26. from types import ClassType
  27. from zope.interface.advice import addClassAdvisor
  28. BuiltinImplementationSpecifications = { }
  29.  
  30. class Declaration(Specification):
  31.     '''Interface declarations
  32.  
  33.     '''
  34.     
  35.     def __init__(self, *interfaces):
  36.         Specification.__init__(self, _normalizeargs(interfaces))
  37.  
  38.     
  39.     def changed(self):
  40.         Specification.changed(self)
  41.         
  42.         try:
  43.             del self._v_attrs
  44.         except AttributeError:
  45.             pass
  46.  
  47.  
  48.     
  49.     def get():
  50.         marker1 = object()
  51.         marker2 = object()
  52.         
  53.         def get(self, name, default = None):
  54.             """Query for an attribute description
  55.  
  56.                 >>> import zope.interface
  57.                 >>> class I1(zope.interface.Interface):
  58.                 ...    a11 = zope.interface.Attribute('a11')
  59.                 ...    a12 = zope.interface.Attribute('a12')
  60.                 >>> class I2(zope.interface.Interface):
  61.                 ...    a21 = zope.interface.Attribute('a21')
  62.                 ...    a22 = zope.interface.Attribute('a22')
  63.                 ...    a12 = zope.interface.Attribute('a212')
  64.                 >>> class I11(I1):
  65.                 ...    a11 = zope.interface.Attribute('a111')
  66.  
  67.                 >>> decl = Declaration(I11, I2)
  68.                 >>> decl.get('a11') is I11.get('a11')
  69.                 True
  70.                 >>> decl.get('a12') is I1.get('a12')
  71.                 True
  72.                 >>> decl.get('a21') is I2.get('a21')
  73.                 True
  74.                 >>> decl.get('a22') is I2.get('a22')
  75.                 True
  76.                 >>> decl.get('a')
  77.                 >>> decl.get('a', 42)
  78.                 42
  79.  
  80.             We get None even with no interfaces:
  81.  
  82.                 >>> decl = Declaration()
  83.                 >>> decl.get('a11')
  84.                 >>> decl.get('a11', 42)
  85.                 42
  86.  
  87.             We get new data if e change interface bases:
  88.  
  89.                 >>> decl.__bases__ = I11, I2
  90.                 >>> decl.get('a11') is I11.get('a11')
  91.                 True
  92.             """
  93.             
  94.             try:
  95.                 attrs = self._v_attrs
  96.             except AttributeError:
  97.                 attrs = self._v_attrs = { }
  98.  
  99.             attr = attrs.get(name, marker1)
  100.             if attr is marker1:
  101.                 for iface in self:
  102.                     attr = iface.get(name, marker2)
  103.                     if attr is not marker2:
  104.                         break
  105.                         continue
  106.                 else:
  107.                     attr = marker2
  108.                 attrs[name] = attr
  109.             
  110.             if attr is marker2:
  111.                 return default
  112.             else:
  113.                 return attr
  114.  
  115.         return get
  116.  
  117.     get = get()
  118.     
  119.     def __contains__(self, interface):
  120.         '''Test whether an interface is in the specification
  121.  
  122.         for example::
  123.  
  124.           >>> from zope.interface import Interface
  125.           >>> class I1(Interface): pass
  126.           ...
  127.           >>> class I2(I1): pass
  128.           ...
  129.           >>> class I3(Interface): pass
  130.           ...
  131.           >>> class I4(I3): pass
  132.           ...
  133.           >>> spec = Declaration(I2, I3)
  134.           >>> spec = Declaration(I4, spec)
  135.           >>> int(I1 in spec)
  136.           0
  137.           >>> int(I2 in spec)
  138.           1
  139.           >>> int(I3 in spec)
  140.           1
  141.           >>> int(I4 in spec)
  142.           1
  143.         '''
  144.         if self.extends(interface):
  145.             pass
  146.         return interface in self.interfaces()
  147.  
  148.     
  149.     def __iter__(self):
  150.         """Return an iterator for the interfaces in the specification
  151.  
  152.         for example::
  153.  
  154.           >>> from zope.interface import Interface
  155.           >>> class I1(Interface): pass
  156.           ...
  157.           >>> class I2(I1): pass
  158.           ...
  159.           >>> class I3(Interface): pass
  160.           ...
  161.           >>> class I4(I3): pass
  162.           ...
  163.           >>> spec = Declaration(I2, I3)
  164.           >>> spec = Declaration(I4, spec)
  165.           >>> i = iter(spec)
  166.           >>> i.next().getName()
  167.           'I4'
  168.           >>> i.next().getName()
  169.           'I2'
  170.           >>> i.next().getName()
  171.           'I3'
  172.           >>> list(i)
  173.           []
  174.         """
  175.         return self.interfaces()
  176.  
  177.     
  178.     def flattened(self):
  179.         """Return an iterator of all included and extended interfaces
  180.  
  181.         for example::
  182.  
  183.           >>> from zope.interface import Interface
  184.           >>> class I1(Interface): pass
  185.           ...
  186.           >>> class I2(I1): pass
  187.           ...
  188.           >>> class I3(Interface): pass
  189.           ...
  190.           >>> class I4(I3): pass
  191.           ...
  192.           >>> spec = Declaration(I2, I3)
  193.           >>> spec = Declaration(I4, spec)
  194.           >>> i = spec.flattened()
  195.           >>> i.next().getName()
  196.           'I4'
  197.           >>> i.next().getName()
  198.           'I2'
  199.           >>> i.next().getName()
  200.           'I1'
  201.           >>> i.next().getName()
  202.           'I3'
  203.           >>> i.next().getName()
  204.           'Interface'
  205.           >>> list(i)
  206.           []
  207.  
  208.         """
  209.         return iter(self.__iro__)
  210.  
  211.     
  212.     def __sub__(self, other):
  213.         """Remove interfaces from a specification
  214.  
  215.         Examples::
  216.  
  217.           >>> from zope.interface import Interface
  218.           >>> class I1(Interface): pass
  219.           ...
  220.           >>> class I2(I1): pass
  221.           ...
  222.           >>> class I3(Interface): pass
  223.           ...
  224.           >>> class I4(I3): pass
  225.           ...
  226.           >>> spec = Declaration()
  227.           >>> [iface.getName() for iface in spec]
  228.           []
  229.           >>> spec -= I1
  230.           >>> [iface.getName() for iface in spec]
  231.           []
  232.           >>> spec -= Declaration(I1, I2)
  233.           >>> [iface.getName() for iface in spec]
  234.           []
  235.           >>> spec = Declaration(I2, I4)
  236.           >>> [iface.getName() for iface in spec]
  237.           ['I2', 'I4']
  238.           >>> [iface.getName() for iface in spec - I4]
  239.           ['I2']
  240.           >>> [iface.getName() for iface in spec - I1]
  241.           ['I4']
  242.           >>> [iface.getName() for iface
  243.           ...  in spec - Declaration(I3, I4)]
  244.           ['I2']
  245.  
  246.         """
  247.         return [](*_[1])
  248.  
  249.     
  250.     def __add__(self, other):
  251.         """Add two specifications or a specification and an interface
  252.  
  253.  
  254.         Examples::
  255.  
  256.           >>> from zope.interface import Interface
  257.           >>> class I1(Interface): pass
  258.           ...
  259.           >>> class I2(I1): pass
  260.           ...
  261.           >>> class I3(Interface): pass
  262.           ...
  263.           >>> class I4(I3): pass
  264.           ...
  265.           >>> spec = Declaration()
  266.           >>> [iface.getName() for iface in spec]
  267.           []
  268.           >>> [iface.getName() for iface in spec+I1]
  269.           ['I1']
  270.           >>> [iface.getName() for iface in I1+spec]
  271.           ['I1']
  272.           >>> spec2 = spec
  273.           >>> spec += I1
  274.           >>> [iface.getName() for iface in spec]
  275.           ['I1']
  276.           >>> [iface.getName() for iface in spec2]
  277.           []
  278.           >>> spec2 += Declaration(I3, I4)
  279.           >>> [iface.getName() for iface in spec2]
  280.           ['I3', 'I4']
  281.           >>> [iface.getName() for iface in spec+spec2]
  282.           ['I1', 'I3', 'I4']
  283.           >>> [iface.getName() for iface in spec2+spec]
  284.           ['I3', 'I4', 'I1']
  285.  
  286.         """
  287.         seen = { }
  288.         result = []
  289.         for i in self.interfaces():
  290.             if i not in seen:
  291.                 seen[i] = 1
  292.                 result.append(i)
  293.                 continue
  294.         
  295.         for i in other.interfaces():
  296.             if i not in seen:
  297.                 seen[i] = 1
  298.                 result.append(i)
  299.                 continue
  300.         
  301.         return Declaration(*result)
  302.  
  303.     __radd__ = __add__
  304.     
  305.     def __nonzero__(self):
  306.         '''Test whether there are any interfaces in a specification.
  307.  
  308.         >>> from zope.interface import Interface
  309.         >>> class I1(Interface): pass
  310.         ...
  311.         >>> spec = Declaration(I1)
  312.         >>> int(bool(spec))
  313.         1
  314.         >>> spec = Declaration()
  315.         >>> int(bool(spec))
  316.         0
  317.         '''
  318.         return bool(self.__iro__)
  319.  
  320.  
  321.  
  322. class Implements(Declaration):
  323.     inherit = None
  324.     declared = ()
  325.     __name__ = '?'
  326.     
  327.     def __repr__(self):
  328.         return '<implementedBy %s>' % self.__name__
  329.  
  330.  
  331.  
  332. def implementedByFallback(cls):
  333.     """Return the interfaces implemented for a class' instances
  334.  
  335.       The value returned is an IDeclaration.
  336.  
  337.       for example:
  338.  
  339.         >>> from zope.interface import Interface
  340.         >>> class I1(Interface): pass
  341.         ...
  342.         >>> class I2(I1): pass
  343.         ...
  344.         >>> class I3(Interface): pass
  345.         ...
  346.         >>> class I4(I3): pass
  347.         ...
  348.         >>> class C1(object):
  349.         ...   implements(I2)
  350.         >>> class C2(C1):
  351.         ...   implements(I3)
  352.         >>> [i.getName() for i in implementedBy(C2)]
  353.         ['I3', 'I2']
  354.       """
  355.     
  356.     try:
  357.         spec = cls.__dict__.get('__implemented__')
  358.     except AttributeError:
  359.         spec = getattr(cls, '__implemented__', None)
  360.         if spec is None:
  361.             spec = BuiltinImplementationSpecifications.get(cls)
  362.             if spec is not None:
  363.                 return spec
  364.             
  365.             return _empty
  366.         
  367.         if spec.__class__ == Implements:
  368.             return spec
  369.         
  370.         return Declaration(*_normalizeargs((spec,)))
  371.  
  372.     if isinstance(spec, Implements):
  373.         return spec
  374.     
  375.     if spec is None:
  376.         spec = BuiltinImplementationSpecifications.get(cls)
  377.         if spec is not None:
  378.             return spec
  379.         
  380.     
  381.     spec.__name__ = getattr(cls, '__module__', '?') + '.' + cls.__name__
  382.     
  383.     try:
  384.         cls.__implemented__ = spec
  385.         if not hasattr(cls, '__providedBy__'):
  386.             cls.__providedBy__ = objectSpecificationDescriptor
  387.         
  388.         if isinstance(cls, DescriptorAwareMetaClasses) and '__provides__' not in cls.__dict__:
  389.             cls.__provides__ = ClassProvides(cls, getattr(cls, '__class__', type(cls)))
  390.     except TypeError:
  391.         Implements if spec is not None else []
  392.         Implements if spec is not None else []
  393.         if not isinstance(cls, type):
  394.             raise TypeError('ImplementedBy called for non-type', cls)
  395.         
  396.         BuiltinImplementationSpecifications[cls] = spec
  397.     except:
  398.         Implements if spec is not None else []
  399.  
  400.     return spec
  401.  
  402. implementedBy = implementedByFallback
  403.  
  404. def classImplementsOnly(cls, *interfaces):
  405.     """Declare the only interfaces implemented by instances of a class
  406.  
  407.       The arguments after the class are one or more interfaces or
  408.       interface specifications (IDeclaration objects).
  409.  
  410.       The interfaces given (including the interfaces in the
  411.       specifications) replace any previous declarations.
  412.  
  413.       Consider the following example::
  414.  
  415.           >>> from zope.interface import Interface
  416.           >>> class I1(Interface): pass
  417.           ...
  418.           >>> class I2(Interface): pass
  419.           ...
  420.           >>> class I3(Interface): pass
  421.           ...
  422.           >>> class I4(Interface): pass
  423.           ...
  424.           >>> class A(object):
  425.           ...   implements(I3)
  426.           >>> class B(object):
  427.           ...   implements(I4)
  428.           >>> class C(A, B):
  429.           ...   pass
  430.           >>> classImplementsOnly(C, I1, I2)
  431.           >>> [i.getName() for i in implementedBy(C)]
  432.           ['I1', 'I2']
  433.  
  434.       Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
  435.       whatever interfaces instances of ``A`` and ``B`` implement.
  436.  
  437.       """
  438.     spec = implementedBy(cls)
  439.     spec.__bases__ = tuple(_normalizeargs(interfaces))
  440.     spec.inherit = None
  441.  
  442.  
  443. def classImplements(cls, *interfaces):
  444.     """Declare additional interfaces implemented for instances of a class
  445.  
  446.       The arguments after the class are one or more interfaces or
  447.       interface specifications (IDeclaration objects).
  448.  
  449.       The interfaces given (including the interfaces in the
  450.       specifications) are added to any interfaces previously
  451.       declared.
  452.  
  453.       Consider the following example::
  454.  
  455.  
  456.       for example:
  457.  
  458.       >>> from zope.interface import Interface
  459.       >>> class I1(Interface): pass
  460.       ...
  461.       >>> class I2(Interface): pass
  462.       ...
  463.       >>> class I3(Interface): pass
  464.       ...
  465.       >>> class I4(Interface): pass
  466.       ...
  467.       >>> class I5(Interface): pass
  468.       ...
  469.       >>> class A(object):
  470.       ...   implements(I3)
  471.       >>> class B(object):
  472.       ...   implements(I4)
  473.       >>> class C(A, B):
  474.       ...   pass
  475.       >>> classImplements(C, I1, I2)
  476.       >>> [i.getName() for i in implementedBy(C)]
  477.       ['I1', 'I2', 'I3', 'I4']
  478.       >>> classImplements(C, I5)
  479.       >>> [i.getName() for i in implementedBy(C)]
  480.       ['I1', 'I2', 'I5', 'I3', 'I4']
  481.  
  482.       Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever
  483.       interfaces instances of ``A`` and ``B`` provide.
  484.  
  485.       """
  486.     spec = implementedBy(cls)
  487.     spec.declared += tuple(_normalizeargs(interfaces))
  488.     bases = []
  489.     seen = { }
  490.     for b in spec.declared:
  491.         if b not in seen:
  492.             seen[b] = 1
  493.             bases.append(b)
  494.             continue
  495.         spec
  496.     
  497.     if spec.inherit is not None:
  498.         for c in spec.inherit.__bases__:
  499.             b = implementedBy(c)
  500.             if b not in seen:
  501.                 seen[b] = 1
  502.                 bases.append(b)
  503.                 continue
  504.         
  505.     
  506.     spec.__bases__ = tuple(bases)
  507.  
  508.  
  509. def _implements_advice(cls):
  510.     (interfaces, classImplements) = cls.__dict__['__implements_advice_data__']
  511.     del cls.__implements_advice_data__
  512.     classImplements(cls, *interfaces)
  513.     return cls
  514.  
  515.  
  516. def _implements(name, interfaces, classImplements):
  517.     frame = sys._getframe(2)
  518.     locals = frame.f_locals
  519.     if locals is frame.f_globals or '__module__' not in locals:
  520.         raise TypeError(name + ' can be used only from a class definition.')
  521.     
  522.     if '__implements_advice_data__' in locals:
  523.         raise TypeError(name + ' can be used only once in a class definition.')
  524.     
  525.     locals['__implements_advice_data__'] = (interfaces, classImplements)
  526.     addClassAdvisor(_implements_advice, depth = 3)
  527.  
  528.  
  529. def implements(*interfaces):
  530.     '''Declare interfaces implemented by instances of a class
  531.  
  532.       This function is called in a class definition.
  533.  
  534.       The arguments are one or more interfaces or interface
  535.       specifications (IDeclaration objects).
  536.  
  537.       The interfaces given (including the interfaces in the
  538.       specifications) are added to any interfaces previously
  539.       declared.
  540.  
  541.       Previous declarations include declarations for base classes
  542.       unless implementsOnly was used.
  543.  
  544.       This function is provided for convenience. It provides a more
  545.       convenient way to call classImplements. For example::
  546.  
  547.         implements(I1)
  548.  
  549.       is equivalent to calling::
  550.  
  551.         classImplements(C, I1)
  552.  
  553.       after the class has been created.
  554.  
  555.       Consider the following example::
  556.  
  557.  
  558.         >>> from zope.interface import Interface
  559.         >>> class IA1(Interface): pass
  560.         ...
  561.         >>> class IA2(Interface): pass
  562.         ...
  563.         >>> class IB(Interface): pass
  564.         ...
  565.         >>> class IC(Interface): pass
  566.         ...
  567.         >>> class A(object): implements(IA1, IA2)
  568.         ...
  569.         >>> class B(object): implements(IB)
  570.         ...
  571.  
  572.         >>> class C(A, B):
  573.         ...    implements(IC)
  574.  
  575.         >>> ob = C()
  576.         >>> int(IA1 in providedBy(ob))
  577.         1
  578.         >>> int(IA2 in providedBy(ob))
  579.         1
  580.         >>> int(IB in providedBy(ob))
  581.         1
  582.         >>> int(IC in providedBy(ob))
  583.         1
  584.  
  585.       Instances of ``C`` implement ``I1``, ``I2``, and whatever interfaces
  586.       instances of ``A`` and ``B`` implement.
  587.  
  588.       '''
  589.     _implements('implements', interfaces, classImplements)
  590.  
  591.  
  592. def implementsOnly(*interfaces):
  593.     '''Declare the only interfaces implemented by instances of a class
  594.  
  595.       This function is called in a class definition.
  596.  
  597.       The arguments are one or more interfaces or interface
  598.       specifications (IDeclaration objects).
  599.  
  600.       Previous declarations including declarations for base classes
  601.       are overridden.
  602.  
  603.       This function is provided for convenience. It provides a more
  604.       convenient way to call classImplementsOnly. For example::
  605.  
  606.         implementsOnly(I1)
  607.  
  608.       is equivalent to calling::
  609.  
  610.         classImplementsOnly(I1)
  611.  
  612.       after the class has been created.
  613.  
  614.       Consider the following example::
  615.  
  616.         >>> from zope.interface import Interface
  617.         >>> class IA1(Interface): pass
  618.         ...
  619.         >>> class IA2(Interface): pass
  620.         ...
  621.         >>> class IB(Interface): pass
  622.         ...
  623.         >>> class IC(Interface): pass
  624.         ...
  625.         >>> class A(object): implements(IA1, IA2)
  626.         ...
  627.         >>> class B(object): implements(IB)
  628.         ...
  629.  
  630.         >>> class C(A, B):
  631.         ...    implementsOnly(IC)
  632.  
  633.         >>> ob = C()
  634.         >>> int(IA1 in providedBy(ob))
  635.         0
  636.         >>> int(IA2 in providedBy(ob))
  637.         0
  638.         >>> int(IB in providedBy(ob))
  639.         0
  640.         >>> int(IC in providedBy(ob))
  641.         1
  642.  
  643.  
  644.       Instances of ``C`` implement ``IC``, regardless of what
  645.       instances of ``A`` and ``B`` implement.
  646.  
  647.       '''
  648.     _implements('implementsOnly', interfaces, classImplementsOnly)
  649.  
  650.  
  651. class Provides(Declaration):
  652.     '''Implement __provides__, the instance-specific specification
  653.  
  654.     When an object is pickled, we pickle the interfaces that it implements.
  655.     '''
  656.     
  657.     def __init__(self, cls, *interfaces):
  658.         self._Provides__args = (cls,) + interfaces
  659.         self._cls = cls
  660.         Declaration.__init__(self, *interfaces + (implementedBy(cls),))
  661.  
  662.     
  663.     def __reduce__(self):
  664.         return (Provides, self._Provides__args)
  665.  
  666.     __module__ = 'zope.interface'
  667.     
  668.     def __get__(self, inst, cls):
  669.         """Make sure that a class __provides__ doesn't leak to an instance
  670.  
  671.         For example::
  672.  
  673.           >>> from zope.interface import Interface
  674.           >>> class IFooFactory(Interface): pass
  675.           ...
  676.           
  677.           >>> class C(object):
  678.           ...   pass
  679.  
  680.           >>> C.__provides__ = ProvidesClass(C, IFooFactory)
  681.           >>> [i.getName() for i in C.__provides__]
  682.           ['IFooFactory']
  683.           >>> getattr(C(), '__provides__', 0)
  684.           0
  685.  
  686.         """
  687.         if inst is None and cls is self._cls:
  688.             return self
  689.         
  690.         raise AttributeError, '__provides__'
  691.  
  692.  
  693. ProvidesClass = Provides
  694. InstanceDeclarations = weakref.WeakValueDictionary()
  695.  
  696. def Provides(*interfaces):
  697.     '''Cache instance declarations
  698.  
  699.       Instance declarations are shared among instances that have the
  700.       same declaration.  The declarations are cached in an weak value
  701.       dictionary.
  702.  
  703.       (Note that, in the examples below, we are going to make
  704.        assertions about the size of the weakvalue dictionary.  For the
  705.        assertions to be meaningful, we need to force garbage
  706.        collection to make sure garbage objects are, indeed, removed
  707.        from the system. Depending on how Python is run, we may need to
  708.        make multiple calls to be sure.  We provide a collect function
  709.        to help with this:
  710.  
  711.        >>> import gc
  712.        >>> def collect():
  713.        ...     for i in range(4):
  714.        ...         gc.collect()
  715.  
  716.       )
  717.       
  718.       >>> collect()
  719.       >>> before = len(InstanceDeclarations)
  720.  
  721.       >>> class C(object):
  722.       ...    pass
  723.  
  724.       >>> from zope.interface import Interface
  725.       >>> class I(Interface):
  726.       ...    pass
  727.       
  728.       >>> c1 = C()
  729.       >>> c2 = C()
  730.  
  731.       >>> len(InstanceDeclarations) == before
  732.       1
  733.  
  734.       >>> directlyProvides(c1, I)
  735.       >>> len(InstanceDeclarations) == before + 1
  736.       1
  737.  
  738.       >>> directlyProvides(c2, I)
  739.       >>> len(InstanceDeclarations) == before + 1
  740.       1
  741.  
  742.       >>> del c1
  743.       >>> collect()
  744.       >>> len(InstanceDeclarations) == before + 1
  745.       1
  746.  
  747.       >>> del c2
  748.       >>> collect()
  749.       >>> len(InstanceDeclarations) == before
  750.       1
  751.       
  752.       '''
  753.     spec = InstanceDeclarations.get(interfaces)
  754.     if spec is None:
  755.         spec = ProvidesClass(*interfaces)
  756.         InstanceDeclarations[interfaces] = spec
  757.     
  758.     return spec
  759.  
  760. Provides.__safe_for_unpickling__ = True
  761. DescriptorAwareMetaClasses = (ClassType, type)
  762.  
  763. def directlyProvides(object, *interfaces):
  764.     """Declare interfaces declared directly for an object
  765.  
  766.       The arguments after the object are one or more interfaces or
  767.       interface specifications (IDeclaration objects).
  768.  
  769.       The interfaces given (including the interfaces in the
  770.       specifications) replace interfaces previously
  771.       declared for the object.
  772.  
  773.       Consider the following example::
  774.  
  775.         >>> from zope.interface import Interface
  776.         >>> class I1(Interface): pass
  777.         ...
  778.         >>> class I2(Interface): pass
  779.         ...
  780.         >>> class IA1(Interface): pass
  781.         ...
  782.         >>> class IA2(Interface): pass
  783.         ...
  784.         >>> class IB(Interface): pass
  785.         ...
  786.         >>> class IC(Interface): pass
  787.         ...
  788.         >>> class A(object): implements(IA1, IA2)
  789.         ...
  790.         >>> class B(object): implements(IB)
  791.         ...
  792.  
  793.         >>> class C(A, B):
  794.         ...    implements(IC)
  795.  
  796.         >>> ob = C()
  797.         >>> directlyProvides(ob, I1, I2)
  798.         >>> int(I1 in providedBy(ob))
  799.         1
  800.         >>> int(I2 in providedBy(ob))
  801.         1
  802.         >>> int(IA1 in providedBy(ob))
  803.         1
  804.         >>> int(IA2 in providedBy(ob))
  805.         1
  806.         >>> int(IB in providedBy(ob))
  807.         1
  808.         >>> int(IC in providedBy(ob))
  809.         1
  810.  
  811.       The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
  812.       instances have been declared for instances of ``C``.
  813.  
  814.       To remove directly provided interfaces, use ``directlyProvidedBy`` and
  815.       subtract the unwanted interfaces. For example::
  816.  
  817.         >>> directlyProvides(ob, directlyProvidedBy(ob)-I2)
  818.         >>> int(I1 in providedBy(ob))
  819.         1
  820.         >>> int(I2 in providedBy(ob))
  821.         0
  822.  
  823.       removes I2 from the interfaces directly provided by
  824.       ``ob``. The object, ``ob`` no longer directly provides ``I2``,
  825.       although it might still provide ``I2`` if it's class
  826.       implements ``I2``.
  827.  
  828.       To add directly provided interfaces, use ``directlyProvidedBy`` and
  829.       include additional interfaces.  For example::
  830.  
  831.         >>> int(I2 in providedBy(ob))
  832.         0
  833.         >>> directlyProvides(ob, directlyProvidedBy(ob), I2)
  834.  
  835.       adds I2 to the interfaces directly provided by ob::
  836.  
  837.         >>> int(I2 in providedBy(ob))
  838.         1
  839.  
  840.       """
  841.     cls = getattr(object, '__class__', None)
  842.     if cls is not None and getattr(cls, '__class__', None) is cls:
  843.         if not isinstance(object, DescriptorAwareMetaClasses):
  844.             raise TypeError('Attempt to make an interface declaration on a non-descriptor-aware class')
  845.         
  846.     
  847.     interfaces = _normalizeargs(interfaces)
  848.     if cls is None:
  849.         cls = type(object)
  850.     
  851.     issub = False
  852.     for damc in DescriptorAwareMetaClasses:
  853.         if issubclass(cls, damc):
  854.             issub = True
  855.             break
  856.             continue
  857.     
  858.     if issub:
  859.         object.__provides__ = ClassProvides(object, cls, *interfaces)
  860.     else:
  861.         object.__provides__ = Provides(cls, *interfaces)
  862.  
  863.  
  864. class ClassProvidesBasePy(object):
  865.     
  866.     def __get__(self, inst, cls):
  867.         if cls is self._cls:
  868.             if inst is None:
  869.                 return self
  870.             
  871.             return self._implements
  872.         
  873.         raise AttributeError, '__provides__'
  874.  
  875.  
  876. ClassProvidesBase = ClassProvidesBasePy
  877.  
  878. try:
  879.     import _zope_interface_coptimizations
  880. except ImportError:
  881.     pass
  882.  
  883. from _zope_interface_coptimizations import ClassProvidesBase
  884.  
  885. class ClassProvides(Declaration, ClassProvidesBase):
  886.     """Special descriptor for class __provides__
  887.  
  888.     The descriptor caches the implementedBy info, so that
  889.     we can get declarations for objects without instance-specific
  890.     interfaces a bit quicker.
  891.  
  892.         For example::
  893.  
  894.           >>> from zope.interface import Interface
  895.           >>> class IFooFactory(Interface):
  896.           ...     pass
  897.           >>> class IFoo(Interface):
  898.           ...     pass
  899.           >>> class C(object):
  900.           ...     implements(IFoo)
  901.           ...     classProvides(IFooFactory)
  902.           >>> [i.getName() for i in C.__provides__]
  903.           ['IFooFactory']
  904.  
  905.           >>> [i.getName() for i in C().__provides__]
  906.           ['IFoo']
  907.  
  908.     
  909.     """
  910.     
  911.     def __init__(self, cls, metacls, *interfaces):
  912.         self._cls = cls
  913.         self._implements = implementedBy(cls)
  914.         self._ClassProvides__args = (cls, metacls) + interfaces
  915.         Declaration.__init__(self, *interfaces + (implementedBy(metacls),))
  916.  
  917.     
  918.     def __reduce__(self):
  919.         return (self.__class__, self._ClassProvides__args)
  920.  
  921.     __get__ = ClassProvidesBase.__get__
  922.  
  923.  
  924. def directlyProvidedBy(object):
  925.     '''Return the interfaces directly provided by the given object
  926.  
  927.     The value returned is an IDeclaration.
  928.  
  929.     '''
  930.     provides = getattr(object, '__provides__', None)
  931.     if provides is None or isinstance(provides, Implements):
  932.         return _empty
  933.     
  934.     return Declaration(provides.__bases__[:-1])
  935.  
  936.  
  937. def classProvides(*interfaces):
  938.     """Declare interfaces provided directly by a class
  939.  
  940.       This function is called in a class definition.
  941.  
  942.       The arguments are one or more interfaces or interface
  943.       specifications (IDeclaration objects).
  944.  
  945.       The given interfaces (including the interfaces in the
  946.       specifications) are used to create the class's direct-object
  947.       interface specification.  An error will be raised if the module
  948.       class has an direct interface specification.  In other words, it is
  949.       an error to call this function more than once in a class
  950.       definition.
  951.  
  952.       Note that the given interfaces have nothing to do with the
  953.       interfaces implemented by instances of the class.
  954.  
  955.       This function is provided for convenience. It provides a more
  956.       convenient way to call directlyProvidedByProvides for a class. For
  957.       example::
  958.  
  959.         classProvides(I1)
  960.  
  961.       is equivalent to calling::
  962.  
  963.         directlyProvides(theclass, I1)
  964.  
  965.       after the class has been created.
  966.  
  967.       For example::
  968.  
  969.             >>> from zope.interface import Interface
  970.             >>> class IFoo(Interface): pass
  971.             ...
  972.             >>> class IFooFactory(Interface): pass
  973.             ...
  974.             >>> class C(object):
  975.             ...   implements(IFoo)
  976.             ...   classProvides(IFooFactory)
  977.             >>> [i.getName() for i in C.__providedBy__]
  978.             ['IFooFactory']
  979.             >>> [i.getName() for i in C().__providedBy__]
  980.             ['IFoo']
  981.  
  982.       if equivalent to::
  983.  
  984.             >>> from zope.interface import Interface
  985.             >>> class IFoo(Interface): pass
  986.             ...
  987.             >>> class IFooFactory(Interface): pass
  988.             ...
  989.             >>> class C(object):
  990.             ...   implements(IFoo)
  991.             >>> directlyProvides(C, IFooFactory)
  992.             >>> [i.getName() for i in C.__providedBy__]
  993.             ['IFooFactory']
  994.             >>> [i.getName() for i in C().__providedBy__]
  995.             ['IFoo']
  996.  
  997.  
  998.       """
  999.     frame = sys._getframe(1)
  1000.     locals = frame.f_locals
  1001.     if locals is frame.f_globals or '__module__' not in locals:
  1002.         raise TypeError(name + ' can be used only from a class definition.')
  1003.     
  1004.     if '__provides__' in locals:
  1005.         raise TypeError('classProvides can only be used once in a class definition.')
  1006.     
  1007.     locals['__provides__'] = _normalizeargs(interfaces)
  1008.     addClassAdvisor(_classProvides_advice, depth = 2)
  1009.  
  1010.  
  1011. def _classProvides_advice(cls):
  1012.     interfaces = cls.__dict__['__provides__']
  1013.     del cls.__provides__
  1014.     directlyProvides(cls, *interfaces)
  1015.     return cls
  1016.  
  1017.  
  1018. def moduleProvides(*interfaces):
  1019.     """Declare interfaces provided by a module
  1020.  
  1021.     This function is used in a module definition.
  1022.  
  1023.     The arguments are one or more interfaces or interface
  1024.     specifications (IDeclaration objects).
  1025.  
  1026.     The given interfaces (including the interfaces in the
  1027.     specifications) are used to create the module's direct-object
  1028.     interface specification.  An error will be raised if the module
  1029.     already has an interface specification.  In other words, it is
  1030.     an error to call this function more than once in a module
  1031.     definition.
  1032.  
  1033.     This function is provided for convenience. It provides a more
  1034.     convenient way to call directlyProvides. For example::
  1035.  
  1036.       moduleImplements(I1)
  1037.  
  1038.     is equivalent to::
  1039.  
  1040.       directlyProvides(sys.modules[__name__], I1)
  1041.  
  1042.     """
  1043.     frame = sys._getframe(1)
  1044.     locals = frame.f_locals
  1045.     if locals is not frame.f_globals or '__name__' not in locals:
  1046.         raise TypeError('moduleProvides can only be used from a module definition.')
  1047.     
  1048.     if '__provides__' in locals:
  1049.         raise TypeError('moduleProvides can only be used once in a module definition.')
  1050.     
  1051.     module = sys.modules[__name__]
  1052.     locals['__provides__'] = Provides(type(module), *_normalizeargs(interfaces))
  1053.  
  1054.  
  1055. def ObjectSpecification(direct, cls):
  1056.     """Provide object specifications
  1057.  
  1058.     These combine information for the object and for it's classes.
  1059.  
  1060.     For example::
  1061.  
  1062.         >>> from zope.interface import Interface
  1063.         >>> class I1(Interface): pass
  1064.         ...
  1065.         >>> class I2(Interface): pass
  1066.         ...
  1067.         >>> class I3(Interface): pass
  1068.         ...
  1069.         >>> class I31(I3): pass
  1070.         ...
  1071.         >>> class I4(Interface): pass
  1072.         ...
  1073.         >>> class I5(Interface): pass
  1074.         ...
  1075.         >>> class A(object): implements(I1)
  1076.         ...
  1077.         >>> class B(object): __implemented__ = I2
  1078.         ...
  1079.         >>> class C(A, B): implements(I31)
  1080.         ...
  1081.         >>> c = C()
  1082.         >>> directlyProvides(c, I4)
  1083.         >>> [i.getName() for i in providedBy(c)]
  1084.         ['I4', 'I31', 'I1', 'I2']
  1085.         >>> [i.getName() for i in providedBy(c).flattened()]
  1086.         ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
  1087.         >>> int(I1 in providedBy(c))
  1088.         1
  1089.         >>> int(I3 in providedBy(c))
  1090.         0
  1091.         >>> int(providedBy(c).extends(I3))
  1092.         1
  1093.         >>> int(providedBy(c).extends(I31))
  1094.         1
  1095.         >>> int(providedBy(c).extends(I5))
  1096.         0
  1097.         >>> class COnly(A, B): implementsOnly(I31)
  1098.         ...
  1099.         >>> class D(COnly): implements(I5)
  1100.         ...
  1101.         >>> c = D()
  1102.         >>> directlyProvides(c, I4)
  1103.         >>> [i.getName() for i in providedBy(c)]
  1104.         ['I4', 'I5', 'I31']
  1105.         >>> [i.getName() for i in providedBy(c).flattened()]
  1106.         ['I4', 'I5', 'I31', 'I3', 'Interface']
  1107.         >>> int(I1 in providedBy(c))
  1108.         0
  1109.         >>> int(I3 in providedBy(c))
  1110.         0
  1111.         >>> int(providedBy(c).extends(I3))
  1112.         1
  1113.         >>> int(providedBy(c).extends(I1))
  1114.         0
  1115.         >>> int(providedBy(c).extends(I31))
  1116.         1
  1117.         >>> int(providedBy(c).extends(I5))
  1118.         1
  1119.  
  1120.  
  1121.         nonzero:
  1122.  
  1123.         >>> from zope.interface import Interface
  1124.         >>> class I1(Interface):
  1125.         ...     pass
  1126.         >>> class I2(Interface):
  1127.         ...     pass
  1128.         >>> class C(object):
  1129.         ...     implements(I1)
  1130.         >>> c = C()
  1131.         >>> int(bool(providedBy(c)))
  1132.         1
  1133.         >>> directlyProvides(c, I2)
  1134.         >>> int(bool(providedBy(c)))
  1135.         1
  1136.         >>> class C(object):
  1137.         ...     pass
  1138.         >>> c = C()
  1139.         >>> int(bool(providedBy(c)))
  1140.         0
  1141.         >>> directlyProvides(c, I2)
  1142.         >>> int(bool(providedBy(c)))
  1143.         1
  1144.  
  1145.  
  1146.     """
  1147.     return Provides(cls, direct)
  1148.  
  1149.  
  1150. def getObjectSpecification(ob):
  1151.     provides = getattr(ob, '__provides__', None)
  1152.     if provides is not None:
  1153.         return provides
  1154.     
  1155.     
  1156.     try:
  1157.         cls = ob.__class__
  1158.     except AttributeError:
  1159.         return _empty
  1160.  
  1161.     return implementedBy(cls)
  1162.  
  1163.  
  1164. def providedBy(ob):
  1165.     
  1166.     try:
  1167.         r = ob.__providedBy__
  1168.     except AttributeError:
  1169.         return getObjectSpecification(ob)
  1170.  
  1171.     
  1172.     try:
  1173.         r.extends
  1174.     except AttributeError:
  1175.         
  1176.         try:
  1177.             r = ob.__provides__
  1178.         except AttributeError:
  1179.             return implementedBy(ob.__class__)
  1180.  
  1181.         
  1182.         try:
  1183.             cp = ob.__class__.__provides__
  1184.         except AttributeError:
  1185.             return r
  1186.  
  1187.         if r is cp:
  1188.             return implementedBy(ob.__class__)
  1189.         
  1190.     except:
  1191.         r is cp
  1192.  
  1193.     return r
  1194.  
  1195.  
  1196. class ObjectSpecificationDescriptorPy(object):
  1197.     '''Implement the __providedBy__ attribute
  1198.  
  1199.     The __providedBy__ attribute computes the interfaces peovided by
  1200.     an object.
  1201.     '''
  1202.     
  1203.     def __get__(self, inst, cls):
  1204.         """Get an object specification for an object
  1205.  
  1206.         For example::
  1207.  
  1208.           >>> from zope.interface import Interface
  1209.           >>> class IFoo(Interface): pass
  1210.           ...
  1211.           >>> class IFooFactory(Interface): pass
  1212.           ...
  1213.           >>> class C(object):
  1214.           ...   implements(IFoo)
  1215.           ...   classProvides(IFooFactory)
  1216.           >>> [i.getName() for i in C.__providedBy__]
  1217.           ['IFooFactory']
  1218.           >>> [i.getName() for i in C().__providedBy__]
  1219.           ['IFoo']
  1220.  
  1221.         """
  1222.         if inst is None:
  1223.             return getObjectSpecification(cls)
  1224.         
  1225.         provides = getattr(inst, '__provides__', None)
  1226.         if provides is not None:
  1227.             return provides
  1228.         
  1229.         return implementedBy(cls)
  1230.  
  1231.  
  1232. ObjectSpecificationDescriptor = ObjectSpecificationDescriptorPy
  1233.  
  1234. def _normalizeargs(sequence, output = None):
  1235.     '''Normalize declaration arguments
  1236.  
  1237.     Normalization arguments might contain Declarions, tuples, or single
  1238.     interfaces.
  1239.  
  1240.     Anything but individial interfaces or implements specs will be expanded.
  1241.     '''
  1242.     if output is None:
  1243.         output = []
  1244.     
  1245.     cls = sequence.__class__
  1246.     if InterfaceClass in cls.__mro__ or Implements in cls.__mro__:
  1247.         output.append(sequence)
  1248.     else:
  1249.         for v in sequence:
  1250.             _normalizeargs(v, output)
  1251.         
  1252.     return output
  1253.  
  1254. _empty = Declaration()
  1255.  
  1256. try:
  1257.     import _zope_interface_coptimizations
  1258. except ImportError:
  1259.     pass
  1260.  
  1261. from _zope_interface_coptimizations import implementedBy, providedBy
  1262. from _zope_interface_coptimizations import getObjectSpecification
  1263. from _zope_interface_coptimizations import ObjectSpecificationDescriptor
  1264. objectSpecificationDescriptor = ObjectSpecificationDescriptor()
  1265.